﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using AesonBaseFramework.EntityFramework.BaseEntities;
using ValidationResult = System.ComponentModel.DataAnnotations.ValidationResult;

namespace AesonXamlControls.Inputs
{
    /// <summary>
    /// Interaction logic for AesonTextBox.xaml
    /// </summary>
    public partial class AesonTextBox : UserControl
    { 
        #region Field

        private List<ValidationResult> l;

        public Brush color { get; set; }

        private double fSize { get; set; }

        private bool IsInEditMode { get; set; }

        private bool IsInError { get; set; }

        #endregion Field
        public AesonTextBox()
        {
            InitializeComponent();
            LayoutRoot.DataContext = this;
            color = txb.Background;
            fSize = txb.FontSize;
            btnShowErrors.Visibility = Visibility.Collapsed;
        }

        #region DependencieProperties
        #region ValueDP

        // Using a DependencyProperty as the backing store for string.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(object), typeof(AesonTextBox), new PropertyMetadata(null));

        public object Value
        {
            get { return (object)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        #endregion ValueDP

        #region DescDP

        // Using a DependencyProperty as the backing store for object.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DescProperty =
            DependencyProperty.Register("Desc", typeof(string), typeof(AesonTextBox), new PropertyMetadata(""));

        public string Desc
        {
            get { return (string)GetValue(DescProperty); }
            set { SetValue(DescProperty, value); }
        }

        #endregion DescDP

        #region KeyDP

        // Using a DependencyProperty as the backing store for KeyVal.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty KeyValProperty =
            DependencyProperty.Register("KeyVal", typeof(string), typeof(AesonTextBox), new PropertyMetadata(""));

        public string KeyVal
        {
            get { return (string)GetValue(KeyValProperty); }
            set { SetValue(KeyValProperty, value); }
        }

        #endregion KeyDP
        #endregion

        #region Private Methods

        private async void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e)
        {
            TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
            await Task.Factory.StartNew(() =>
            {
                AesonBaseEntity t = this.DataContext as AesonBaseEntity;
                if (t != null)
                {
                    TextBox b = sender as TextBox;
                    string val = b.Text;
                    string type = KeyVal;
                    l = t.ValidateProperty(type, val);
                    if (l.Count != 0)
                    {
                        // In Error
                        b.Background = Brushes.Red;
                        IsInError = true;
                        btnShowErrors.Visibility = Visibility.Visible;
                    }
                    else
                    {
                        // non error
                        if (b.IsSelectionActive)
                        {
                            b.Background = Brushes.LightGreen;
                            IsInError = false;
                            btnShowErrors.Visibility = Visibility.Collapsed;
                        }
                    }  
                }
              
            }, CancellationToken.None, TaskCreationOptions.None, uiScheduler);
        }

        private void UIElement_OnGotFocus(object sender, RoutedEventArgs e)
        {
            TextBox b = sender as TextBox;
            b.FontSize = fSize + 2;
            lbl.FontWeight = FontWeights.Bold;
            b.FontWeight = FontWeights.Bold;

            if (!IsInError)
            {
                b.Background = Brushes.LightSkyBlue;
            }
            if (b.Text == "")
            {
                IsInEditMode = true;
                b.IsReadOnly = false;
            }
        }

        private void UIElement_OnLostFocus(object sender, RoutedEventArgs e)
        {
            TextBox b = sender as TextBox;
            b.FontSize = fSize;
            lbl.FontWeight = FontWeights.Normal;
            b.FontWeight = FontWeights.Normal;
            if (!IsInError)
            {
                b.Background = color;
            }

            IsInEditMode = false;
            b.IsReadOnly = true;
        }

        private void BtnShowErrors_OnClick(object sender, RoutedEventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var er in l)
            {
                sb.AppendLine(er.ErrorMessage);
            }

            MessageBox.Show(sb.ToString());
        }

        private void Txb_OnKeyDown(object sender, KeyEventArgs e)
        {
            TextBox b = sender as TextBox;
            if (e.Key == Key.Space && IsInEditMode == false)
            {
                IsInEditMode = true;
                b.IsReadOnly = false;
                e.Handled = true;
                b.CaretIndex = b.Text.Length;
            }
            if (IsInEditMode && e.Key == Key.Left && Keyboard.Modifiers == ModifierKeys.Control)
            {
                e.Handled = true;
                b.SelectAll();
            }
        }

        private void Txb_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            TextBox b = sender as TextBox;
            if (IsInEditMode == false)
            {
                IsInEditMode = true;
                b.IsReadOnly = false;
                b.CaretIndex = b.Text.Length;
            }
        }
        #endregion Private Methods
    }
}
